package com.metadata_system.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.metadata_system.common.db.entity.ProjectNode;
import com.metadata_system.common.dto.ApiResult;
import com.metadata_system.common.exception.ApiException;
import com.metadata_system.system.response.NodePropertiesItem;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;

import javax.imageio.ImageIO;
import javax.net.ssl.*;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MyUtil {

    public static Map<String, String> parseUrlParams(String query) {
        Map<String, String> map = new HashMap<>();
        if (!StringUtils.isBlank(query)) {
            String[] split = query.split("&");
            for (String s : split) {
                String[] arr = s.split("=");
                if (arr.length > 1) {
                    map.put(arr[0], arr[1]);
                }
            }
        }
        return map;
    }

    public static ApiResult checkProperties(String properties){
        List<NodePropertiesItem> nodePropertiesItems = JSON.parseArray(properties, NodePropertiesItem.class);
        List<String> keys = new ArrayList<>();
        for (NodePropertiesItem nodePropertiesItem : nodePropertiesItems) {
            if (StringUtils.isBlank(nodePropertiesItem.getLabel())){
                return ApiResult.error("参数 "+nodePropertiesItem.getLabel()+" 不能为空");
            }
            if(keys.contains(nodePropertiesItem.getProp())){
                return ApiResult.success("参数 "+nodePropertiesItem.getProp()+" 重复");
            }
            keys.add(nodePropertiesItem.getProp());
        }
        return ApiResult.success();
    }



    public static String handlerAddressDetail(String addressDetail){
        String[] s = addressDetail.split(" ");

        String[] splitArr = s[0].split(",");
        List<String> list = Arrays.asList(splitArr);
        if (list.get(0).equals(list.get(1))){
            list=MyUtil.removeList(list,0);
        }else{
            if (list.get(1).equals(list.get(2))){
                list=MyUtil.removeList(list,1);
            }
        }
        s[0]=MyUtil.join(list,",");
        return s[0]+" "+s[1];
    }


    public static List removeList(List list,int index){
        List<Object> newList=new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (i!=index){
                newList.add(list.get(i));
            }
        }
        return newList;
    }

    /**
     * 首字母大写
     *
     * @param name
     * @return
     */
    public static String captureName(String name) {
        char[] cs = name.toCharArray();
        cs[0] -= 32;
        return String.valueOf(cs);

    }

    /**
     * 替换所有空白字符
     *
     * @param str
     * @return
     */
    public static String replaceBlank(String str) {
        String dest = null;
        if (str == null) {
            return dest;
        } else {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
            return dest;
        }
    }

    /**
     * 是否全空字符
     *
     * @param str
     * @return
     */
    public static Boolean isAllBlank(String str) {
        str = replaceBlank(str);
        return StringUtils.isBlank(str);
    }

    private static Pattern linePattern = Pattern.compile("_(\\w)");

    /**
     * 下划线转驼峰
     */
    public static String lineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 驼峰转下划线
     *
     * @param str
     * @return
     */
    public static String humpToLine(String str) {
        return str.replaceAll("[A-Z]", "_$0").toLowerCase();
    }


    public static String[] HandlerTime(String businessTime) {
        String[] split = businessTime.split(",");
        return new String[]{split[0].substring(0, 2) + ":" + split[0].substring(2, 4) + ":00", split[1].substring(0, 2) + ":" + split[1].substring(2, 4) + ":00"};
    }

    public static void main(String[] args) {
        System.out.println(getRandomString(10));
    }


    public static String getRandomString(int length) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    public static String join(List list, String split) {
        StringBuffer stringBuffer = new StringBuffer();
        int i = 0;
        for (Object item : list) {
            if (i < list.size() - 1) {
                stringBuffer.append(item.toString() + split);
            } else {
                stringBuffer.append(item.toString());
            }
            i++;
        }
        return stringBuffer.toString();
    }


//    public static void main(String[] args) {
//        System.out.println("formatDateArr: "+JSON.toJSONString(MyUtil.formatDateArr("2022-01-08,2022-01-18")));
//    }

    public static String EncryptionMobile(String mobile) {
        return mobile.substring(0, 3) + "****" + mobile.substring(7, 11);
    }

    /**
     * 格式化-时间段
     *
     * @param dateString
     * @return
     */
    public static String[] formatDateArr(String dateString) {
        String[] split = dateString.split(",");
        try {
            Date date1 = new Date();
            Date date2 = new Date();
            String str1 = null;
            String str2 = null;
            String formatString = DateTimeUtil.FMT_yyyyMMdd;
            if (!StringUtils.isBlank(split[0])) {
                // 格式: 2022年9月21日
                if (split[0].length() >= 6 && split[0].length() <= 10) {
                    formatString = DateTimeUtil.FMT_yyyyMMdd;
                }
                // 格式: 2022-09-21 07:06:19
                if (split[0].length() >= 12 && split[0].length() <= 19) {
                    formatString = DateTimeUtil.FMT_yyyyMMddHHmmss;
                }
                if (formatString.equals(DateTimeUtil.FMT_yyyyMMdd)) {
                    date1 = DateTimeUtil.parseToDate(split[0] + " 00:00:00", formatString);
                    str1 = DateTimeUtil.formatDateTimetoString(date1, DateTimeUtil.FMT_yyyyMMddHHmmss);
                }
                if (formatString.equals(DateTimeUtil.FMT_yyyyMMddHHmmss)) {
                    date1 = DateTimeUtil.parseToDate(split[0], formatString);
                    str1 = DateTimeUtil.formatDateTimetoString(date1, formatString);
                }
            }
            if (!StringUtils.isBlank(split[1])) {
                // 格式: 2022年9月21日
                if (split[1].length() >= 6 && split[1].length() <= 10) {
                    formatString = DateTimeUtil.FMT_yyyyMMdd;
                }
                // 格式: 2022-09-21 07:06:19
                if (split[1].length() >= 12 && split[1].length() <= 19) {
                    formatString = DateTimeUtil.FMT_yyyyMMddHHmmss;
                }
                if (formatString.equals(DateTimeUtil.FMT_yyyyMMdd)) {
                    date2 = DateTimeUtil.parseToDate(split[1] + " 23:59:59", DateTimeUtil.FMT_yyyyMMddHHmmss);
                    str2 = DateTimeUtil.formatDateTimetoString(date2, DateTimeUtil.FMT_yyyyMMddHHmmss);
                }
                if (formatString.equals(DateTimeUtil.FMT_yyyyMMddHHmmss)) {
                    date2 = DateTimeUtil.parseToDate(split[1], formatString);
                    str2 = DateTimeUtil.formatDateTimetoString(date2, formatString);
                }
            }
            return new String[]{str1, str2};
        } catch (Exception e) {
            return null;
//            throw new RuntimeException(e);
        }
    }

    /**
     * 读取文件内容
     *
     * @param filePath
     * @return
     */
    public static String readFile(String filePath) {
        try {
            File file = new File(filePath);
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] bytes = new byte[fileInputStream.available()];
            fileInputStream.read(bytes);
            return new String(bytes);
        } catch (Exception e) {
            return "";
        }
    }


//    public static void main(String[] args) {
//        HashMap<String, Object> tmpMap = new HashMap<>();
//
//        tmpMap.put("12月30日",1);
//        tmpMap.put("12月31日",2);
//        tmpMap.put("01月01日",3);
//        tmpMap.put("01月02日",4);
//        tmpMap.put("01月03日",5);
//
//        Map<String, Object> tmp = sortMapByKey(tmpMap);
//        System.out.println("结果: "+ JSON.toJSONString(tmp));
//    }

    /**
     * map按照key排序
     *
     * @param map
     * @return
     */
    public static Map<String, Object> sortMapByKey(Map<String, Object> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Map<String, Object> sortMap = new TreeMap<String, Object>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
//                if (o1.contains("01月") && o2.contains("12月")){
//                    return 1;
//                }
//                if (o1.contains("12月") && o2.contains("01月")){
//                    return -1;
//                }
//                System.out.println("=====================");
//                System.out.println("o1: "+o1);
//                System.out.println("o2: "+o2);
//                System.out.println("=====================");
                return ((String) o1).compareTo((String) o2);
            }
        });
        sortMap.putAll(map);
        return sortMap;
    }

    public static Integer MoneyToFen(BigDecimal money) {
        money = money.multiply(BigDecimal.valueOf(100));
        String[] split = money.toString().split("\\.");
        Integer realMoney = Integer.valueOf(split[0]);
        return realMoney;
    }

    @SneakyThrows
    public static void test(String apiUrl) {
        URL url = new URL(apiUrl);
        URLConnection urlConnection = url.openConnection();


        InputStream inputStream = urlConnection.getInputStream();
        Scanner scanner = new Scanner(inputStream);
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            System.out.println(line);
        }
        scanner.close();
    }

    /**
     * 信任所有ssl证书,请求api
     *
     * @param apiUrl
     */
    @SneakyThrows
    public static void httpGetTrustAll(String apiUrl) {
        // 创建信任管理器，信任所有证书
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };

        // 创建SSL上下文
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());

        // 打开HTTPS连接，并信任所有证书
        URL url = new URL(apiUrl);
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        connection.setSSLSocketFactory(sc.getSocketFactory());

        // 执行HTTPS请求
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        }
    }


/*    public static void main(String[] args) {
//        MovToMp4("C:\\Users\\lxh20\\Desktop\\a.mov","C:\\Users\\lxh20\\Desktop\\a1.mp4");
    }*/



    public static List<String[]> parseSearchDateType(String type) {
        List<String[]> dateList = new ArrayList<>();
        String olddestStartTime = "1970-01-01 00:00:00";
        Date currDate = new Date();
        String tomorrowDay = DateTimeUtil.formatDateTimetoString(DateTimeUtil.getTomorrow(currDate), DateTimeUtil.FMT_yyyyMMdd);
        if (type.equals("currDay")) {
            String today = DateTimeUtil.formatDateTimetoString(currDate, DateTimeUtil.FMT_yyyyMMdd);
            dateList.add(new String[]{today + " 00:00:00", tomorrowDay + " 00:00:00"});
            dateList.add(new String[]{olddestStartTime, today + " 00:00:00"});
            return dateList;
        }
        if (type.equals("currWeek")) {
            String today = DateTimeUtil.formatDateTimetoString(currDate, DateTimeUtil.FMT_yyyyMMdd);
            int dayOfWeek = DateTimeUtil.getDayOfWeek(currDate);
            HashMap<Integer, Integer> weekDaySubNums = new HashMap<>();
            weekDaySubNums.put(0, 6);
            weekDaySubNums.put(6, 5);
            weekDaySubNums.put(5, 4);
            weekDaySubNums.put(4, 3);
            weekDaySubNums.put(3, 2);
            weekDaySubNums.put(2, 1);
            weekDaySubNums.put(1, 0);
            Date startDay = DateTimeUtil.addDays(currDate, -weekDaySubNums.get(dayOfWeek));
            String startDayString = DateTimeUtil.formatDateTimetoString(startDay, DateTimeUtil.FMT_yyyyMMdd);
            dateList.add(new String[]{startDayString + " 00:00:00", tomorrowDay + " 00:00:00"});
            dateList.add(new String[]{olddestStartTime, startDayString + " 00:00:00"});
            return dateList;
        }
        if (type.equals("currMonth")) {
            String today = DateTimeUtil.formatDateTimetoString(currDate, DateTimeUtil.FMT_yyyyMMdd);
            int dayOfMonth = DateTimeUtil.getDayOfMonth(currDate);
            Date startDay = DateTimeUtil.addDays(currDate, -dayOfMonth);
            String startDayString = DateTimeUtil.formatDateTimetoString(startDay, DateTimeUtil.FMT_yyyyMMdd);
            dateList.add(new String[]{startDayString + " 00:00:00", tomorrowDay + " 00:00:00"});
            dateList.add(new String[]{olddestStartTime, startDayString + " 00:00:00"});
            return dateList;
        }
        if (type.equals("currYear")) {
            String today = DateTimeUtil.formatDateTimetoString(currDate, DateTimeUtil.FMT_yyyyMMdd);
            int dayOfYear = DateTimeUtil.getDayOfYear(currDate);
            Date startDay = DateTimeUtil.addDays(currDate, -dayOfYear);
            String startDayString = DateTimeUtil.formatDateTimetoString(startDay, DateTimeUtil.FMT_yyyyMMdd);
            dateList.add(new String[]{startDayString + " 00:00:00", tomorrowDay + " 00:00:00"});
            dateList.add(new String[]{olddestStartTime, startDayString + " 00:00:00"});
            return dateList;
        }
        if (type.equals("7days")) {
            String today = DateTimeUtil.formatDateTimetoString(currDate, DateTimeUtil.FMT_yyyyMMdd);
            Date startDay = DateTimeUtil.addDays(currDate, -7);
            String startDayString = DateTimeUtil.formatDateTimetoString(startDay, DateTimeUtil.FMT_yyyyMMdd);
            dateList.add(new String[]{startDayString + " 00:00:00", tomorrowDay + " 00:00:00"});
            dateList.add(new String[]{olddestStartTime, startDayString + " 00:00:00"});
            return dateList;
        }
        if (type.equals("10days")) {
            String today = DateTimeUtil.formatDateTimetoString(currDate, DateTimeUtil.FMT_yyyyMMdd);
            Date startDay = DateTimeUtil.addDays(currDate, -10);
            String startDayString = DateTimeUtil.formatDateTimetoString(startDay, DateTimeUtil.FMT_yyyyMMdd);
            dateList.add(new String[]{startDayString + " 00:00:00", tomorrowDay + " 00:00:00"});
            dateList.add(new String[]{olddestStartTime, startDayString + " 00:00:00"});
            return dateList;
        }
        if (type.equals("30days")) {
            String today = DateTimeUtil.formatDateTimetoString(currDate, DateTimeUtil.FMT_yyyyMMdd);
            Date startDay = DateTimeUtil.addDays(currDate, -30);
            String startDayString = DateTimeUtil.formatDateTimetoString(startDay, DateTimeUtil.FMT_yyyyMMdd);
            dateList.add(new String[]{startDayString + " 00:00:00", tomorrowDay + " 00:00:00"});
            dateList.add(new String[]{olddestStartTime, startDayString + " 00:00:00"});
            return dateList;
        }
        return null;
    }


    public static String showHtml(String title, String body) {
        return "<!DOCTYPE html>\n" +
                "<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>" + title + "</title>\n" +
                "</head>\n" +
                "<body>\n" +
                body +
                "</body>\n" +
                "</html>\n";
    }

//    public static void main(String[] args) {
//        System.out.println("n: "+ JSON.toJSONString(MyUtil.parseSearchDateType("currWeek")));
//    }


//    public static Boolean checkBusinessTime(String businessTime){
//        String[] businessTimeArr = businessTime.split(",");
//        Date date = new Date();
//        Integer hours = Integer.valueOf(DateTimeUtil.getHoursOfDay(date)) * 100;
//        Integer minutes = Integer.valueOf(DateTimeUtil.getMinutesOfHour(date));
//        if (!(Integer.valueOf(businessTimeArr[0]).compareTo(hours + minutes) < 0 && Integer.valueOf(businessTimeArr[1]).compareTo(hours + minutes) > 0)) {
//            return false;
//        }
//        return true;
//    }

    public static String checkTimeArr(String timeStr) {
        String[] timeArr = timeStr.replace(":", "").split(",");
        timeArr[0] = String.format("%04d", Integer.valueOf(timeArr[0]));
        timeArr[1] = String.format("%04d", Integer.valueOf(timeArr[1]));
        return timeArr[0] + "," + timeArr[1];
    }





    public static String getFileSuffix(String file){
        String[] split = file.split("\\.");
        if (split.length>1){
            return split[split.length-1];
        }
        return "";
    }

    public static void compressImage(String imagePath,String outputFilePath,int targetWidth){
        try {
            // 图片文件路径
//            int targetWidth = 800;

            // 读取图片
            BufferedImage originalImage = ImageIO.read(new File(imagePath));

            // 计算压缩比例
            double scale = (double) targetWidth / originalImage.getWidth();

            // 创建新的宽度，高度按比例调整
            int newHeight = (int) (originalImage.getHeight() * scale);

            // 创建压缩后的图片
            BufferedImage compressedImage = new BufferedImage(targetWidth, newHeight, originalImage.getType());
            compressedImage.getGraphics().drawImage(originalImage.getScaledInstance(targetWidth, newHeight, BufferedImage.SCALE_SMOOTH), 0, 0, null);

            // 保存压缩后的图片
//            File outputFile = new File("path/to/output/image.jpg");
            ImageIO.write(compressedImage, "jpg", new File(outputFilePath));

            System.out.println("图片压缩完成: "+outputFilePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    public static String generateOrderNo(){
        String datetime=String.valueOf((new Date()).getTime()/1000).substring(2,10);
        return datetime+String.format("%03d", RandomUtils.nextInt(999));
    }

    public static String generateUTCTime(String dateTime) throws Exception {
        Date date = DateTimeUtil.parseToDate(dateTime);
        // 创建一个SimpleDateFormat对象用于格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

        // 设置时区为UTC
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

        // 使用SimpleDateFormat格式化Date对象
        return sdf.format(date);
    }


    public static String getRequestParameter(String parameterName) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            return request.getParameter(parameterName);
        } else {
            return null;
        }
    }

    public static String getRequestHeader(String headerName) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            return request.getHeader(headerName);
        } else {
            return null;
        }
    }


    public static Boolean isMobileUserAgent(String userAgent){
        List<String> keywords=Arrays.asList("Mobile,iPhone,Android".split(","));
        boolean isMobile=false;
        for (String keyword : keywords) {
            if (!isMobile){
                isMobile=userAgent.contains(keyword);
            }
        }
        return isMobile;
    }



    public static List<String> getConditionList(Map<String,Object> searchMap, ProjectNode projectNode) {
        if (searchMap == null || searchMap.isEmpty()) {
            searchMap = new HashMap<>();
        }
        List<String> conditionList = NodePropertiesItem.ParseMapToCondition(searchMap, projectNode.getMetadataNodeProperties());
        conditionList.add("1=1");
        if (searchMap.get("createdTime") != null) {
            String[] split = searchMap.get("createdTime").toString().split(",");
            if (split.length == 2) {
                if (!StringUtils.isBlank(split[0])) {
                    try {
                        DateTimeUtil.parseToDate(split[0],DateTimeUtil.FMT_yyyyMMdd);
                        conditionList.add("createdTime>='" + split[0]+" 00:00:00'");
                    } catch (Exception e) {
                        throw new ApiException("创建时间 格式错误1");
                    }
                }
                if (!StringUtils.isBlank(split[1])) {
                    try {
                        DateTimeUtil.parseToDate(split[1],DateTimeUtil.FMT_yyyyMMdd);
                        conditionList.add("createdTime<='"+ split[1]+" 23:59:59'");
                    } catch (Exception e) {
                        throw new ApiException("创建时间 格式错误2");
                    }
                }
            }
        }
        return conditionList;
    }
}

